﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Jemgine.Engine
{
    [Category("Draw"), Component]
    public class AnimatedSkeleton : Jemgine.Engine.EntityComponent
    {
        [Microsoft.Xna.Framework.Content.ContentSerializerIgnore]
        Jemgine.Data.Animation CurrentAnimation = null;

        [Microsoft.Xna.Framework.Content.ContentSerializerIgnore]
        Jemgine.Animation.AnimationPlayer AnimationPlayer = null;

        public AnimatedSkeleton()
        {
            AddReference("Skeleton", typeof(Data.Skeleton));
        }

        public override void _Initialize(Microsoft.Xna.Framework.Content.ContentManager Content)
        {
            AnimationPlayer = new Jemgine.Animation.AnimationPlayer();
            var Module = Sim.GetModule<AnimationModule>();
            if (Module != null) Module.Add(this);
            base._Initialize(Content);
        }

        public override void _Destroy()
        {
            var Module = Sim.GetModule<AnimationModule>();
            if (Module != null) Module.Remove(this);
            base._Destroy();
        }

        
        public void Update(float ElapsedSeconds)
        {
            AnimationPlayer.Update(ElapsedSeconds);
            var Skeleton = ReferenceTerminals[0].GetTarget() as Data.Skeleton;
            if (Skeleton != null)
            {
                if (CurrentAnimation != null)
                {
                    float FrameTime = AnimationPlayer.GetFloatTime();
                    int StartFrame = (int)System.Math.Floor(FrameTime);
                    int EndFrame = StartFrame + 1;
                    if (EndFrame >= CurrentAnimation.Frames.Count) EndFrame = 0;
                    float Percentage = FrameTime - (float)StartFrame;
                    Skeleton.SetTransform(Data.Skeleton.BlendFrameAngles(
                        Skeleton.GetFrameAngles(CurrentAnimation.Frames[StartFrame]),
                        Skeleton.GetFrameAngles(CurrentAnimation.Frames[EndFrame]),
                        Percentage));
                }
                else
                    Skeleton.SetIdentityTransform();
            }
        }

        public void Play(String AnimationName, bool Loop)
        {
            var Skeleton = ReferenceTerminals[0].GetTarget() as Data.Skeleton;
            if (Skeleton != null)
            {
                CurrentAnimation = Skeleton.Animations.FirstOrDefault((A) => { return A.Name == AnimationName; });
            }
            if (CurrentAnimation != null)
                AnimationPlayer.Play(CurrentAnimation.Rate, CurrentAnimation.Frames.Count, Loop);
        }

        public void HotPlay(String AnimationName)
        {
            var Skeleton = ReferenceTerminals[0].GetTarget() as Data.Skeleton;
            if (Skeleton != null)
            {
                CurrentAnimation = Skeleton.Animations.FirstOrDefault((A) => { return A.Name == AnimationName; });
            }
            if (CurrentAnimation != null)
                AnimationPlayer.HotPlay(CurrentAnimation.Rate, CurrentAnimation.Frames.Count, true);
        }
    }
}
